package com.demon.mutehelper

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.util.Log
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.versionedparcelable.ParcelField
import androidx.versionedparcelable.VersionedParcelize
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItems
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.LocationSource
import com.amap.api.maps.MapsInitializer
import com.amap.api.maps.model.BitmapDescriptor
import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.MyLocationStyle
import com.amap.api.services.core.PoiItem
import com.amap.api.services.geocoder.GeocodeQuery
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeResult
import com.amap.api.services.help.Inputtips
import com.amap.api.services.help.InputtipsQuery
import com.amap.api.services.help.Tip
import com.amap.api.services.poisearch.PoiResult
import com.amap.api.services.poisearch.PoiSearch
import com.demon.mutehelper.databinding.ActivityMapBinding
import java.io.Serializable

class MapActivity : AppCompatActivity() {
  private lateinit var mBinding: ActivityMapBinding
  private var mMapViewBundle: Bundle? = null
  private var mMap: AMap? = null
  private var mLocationClient: AMapLocationClient? = null
  private lateinit var geoCodeSearch: GeocodeSearch
  private var mCityCode: String? = null
  override fun onCreate(savedInstanceState: Bundle?) {
    MapsInitializer.updatePrivacyAgree(this, true)
    MapsInitializer.updatePrivacyShow(this, true, true)
    super.onCreate(savedInstanceState)
    mBinding = DataBindingUtil.setContentView(this, R.layout.activity_map)

    mMapViewBundle = savedInstanceState?.getBundle(BUNDLE_KEY_MAP_VIEW)
    mBinding.mapView.apply {
      onCreate(mMapViewBundle)
    }
    mMap = mBinding.mapView.map
    initView()
    initMap()
    startLocation()
  }

  private fun initView() {
//    mBinding.searchInput.setOnKeyListener { view, i, keyEvent ->
//      if(keyEvent.a)
//    }
    mBinding.searchInput.setOnEditorActionListener { textView, i, keyEvent ->
      if (EditorInfo.IME_ACTION_SEARCH == i) {
        hideKeyboard(textView)
        if (textView.text.isNotEmpty()) {
          searchMap(textView.text.toString())
        }
        true
      } else {
        false
      }

    }
  }

  private fun hideKeyboard(textView: TextView) {
    val imm =
      textView.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
    if (imm.isActive) {
      imm.hideSoftInputFromWindow(textView.applicationWindowToken, 0)
    }
  }

  private val poiSearchListener = object : PoiSearch.OnPoiSearchListener {
    override fun onPoiSearched(p0: PoiResult?, p1: Int) {
      val markerOptionsList = ArrayList<MarkerOptions>()
      p0?.pois?.forEach {
        Log.d("YZZ", "${it.title}")
        markerOptionsList.add(
          MarkerOptions()
            .position(LatLng(it.latLonPoint.latitude, it.latLonPoint.longitude))
            .title(it.adName)
            .snippet(it.snippet)
        )
      }
//      mMap?.addMarkers(markerOptionsList, false)
    }

    override fun onPoiItemSearched(p0: PoiItem?, p1: Int) {
      p0?.apply { Log.d("YZZ", "onPoiItemSearched ${this.title}") }
    }

  }

  private fun searchMap(text: String) {
//    mCityCode.let { cityCode ->
//      val query = PoiSearch.Query(text, "", cityCode)
//      val poiSearch = PoiSearch(this, query)
//      poiSearch.setOnPoiSearchListener(poiSearchListener)
//      poiSearch.searchPOIAsyn()
//    }
    val inputQuery = InputtipsQuery(text, mCityCode)
    inputQuery.cityLimit = true
    val inputtips = Inputtips(this, inputQuery)
    inputtips.setInputtipsListener { mutableList, i ->
      showDialog(tips = mutableList)
    }
    inputtips.requestInputtipsAsyn()
  }

  @SuppressLint("CheckResult")
  private fun showDialog(tips: List<Tip>) {

    MaterialDialog(this).show {
      listItems(items = tips.map { it.name }) { dialog, index, text ->
        setResult(
          RESULT_OK,
          Intent().apply {
            putExtra(
              RESULT_BUNDLE_KEY_MAP_CHOSEN,
              MapChosenBean(
                tips[index].name,
                tips[index].point?.latitude,
                tips[index].point?.longitude
              )
            )
          })
        finish()
      }
    }
  }

  private fun initMap() {
    mMap?.setOnMapClickListener {
      clearInputFocusAndHideKeyboard()
    }
  }

  private fun clearInputFocusAndHideKeyboard() {
    mBinding.searchInput.clearFocus()
    hideKeyboard(mBinding.searchInput)
  }

  private fun startLocation() {
    AMapLocationClient.updatePrivacyAgree(this, true)
    AMapLocationClient.updatePrivacyShow(this, true, true)
    val myLocationStyle = MyLocationStyle()
    myLocationStyle.showMyLocation(true)
    myLocationStyle.interval(2000L).myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW)
    mMap?.myLocationStyle = myLocationStyle
//    mMap?.isMyLocationEnabled = true
//    mMap?.addOnMyLocationChangeListener {
//
//    }
    mLocationClient = AMapLocationClient(applicationContext).apply {
      setLocationListener {
        it?.apply {
          mCityCode = it.cityCode
          Log.d("YZZ", it.adCode)
          Log.d("YZZ", "lat ${it.latitude}， lon ${it.longitude}")
          mMap?.moveCamera(
            CameraUpdateFactory.newLatLngZoom(
              LatLng(it.latitude, it.longitude),
              19f
            )
          )
          Log.d("YZZ", "moveCamera")
        }
      }
    }
    val locationClientOption = AMapLocationClientOption().apply {
      locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
      isOnceLocation = true
    }
    mLocationClient?.setLocationOption(locationClientOption)
    mLocationClient?.stopLocation()
    mLocationClient?.startLocation()
  }

  override fun onDestroy() {
    super.onDestroy()
    mBinding.mapView.onDestroy()
    mLocationClient?.onDestroy()
  }

  override fun onResume() {
    super.onResume()
    mBinding.mapView.onResume()
  }

  override fun onPause() {
    super.onPause()
    mBinding.mapView.onPause()
    mLocationClient?.stopLocation()
  }

  override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    mBinding.mapView.onSaveInstanceState(outState)
  }

  inner class ClickHandler {
    fun onSearchTextChanged(text: Editable) {

    }
  }

  data class MapChosenBean(val name: String, val lat: Double?, val lon: Double?) : Serializable

  companion object {
    const val RESULT_BUNDLE_KEY_MAP_CHOSEN = "result_bundle_key_map_chosen"
    private const val BUNDLE_KEY_MAP_VIEW = "bundle_key_map_view"
  }
}